package schedule;


import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.TimeZone;

import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.Description;
import net.fortuna.ical4j.model.property.Location;
import net.fortuna.ical4j.model.property.Uid;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.EventWho;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.extensions.Where;

/**
 * Represente un evenement
 * @author Stanislas KOBAK / Celine BARILLERE
 *
 */
public class Event
{
	private String subject;
	private String place;
	private DateTime startDate;
	private int duration;
	private List<String> persons;
	
	/**
	 * Constructeur par defaut
	 */
	public Event()
	{
		subject = "";
		place = "";
		startDate = new DateTime();
		duration = 0;
		persons = new LinkedList<String>();
	}
	
	/**
	 * Constructeur
	 * @param subject L'intitule de l'evenement
	 * @param place Le lieu de l'evenement
	 * @param startDate La date du debut de l'evenement
	 * @param duration La duree de l'evenement en minutes
	 * @param persons La liste des personnes concernees par l'evenement
	 */ 
	public Event(String subject, String place, DateTime startDate, int duration, List<String> persons)
	{
		this.subject = subject;
		this.place = place;
		this.startDate = startDate;
		this.duration = duration;
		this.persons = persons;
	}
	
	/**
	 * Constructeur
	 * @param vEvent
	 */ 
	public Event(VEvent vEvent)
	{
		DateTimeFormatter formatter = ISODateTimeFormat.basicDateTimeNoMillis();
		DateTime start = formatter.parseDateTime(vEvent.getStartDate().getValue());
		DateTime end = formatter.parseDateTime(vEvent.getEndDate().getValue());
		Period period = new Period(start, end);
		
		String summary = vEvent.getSummary().getValue();
		String location = vEvent.getLocation().getValue();
		
		subject = summary;
		place = location;
		startDate = start;
		duration = period.toStandardMinutes().getMinutes();
		persons = new LinkedList<String>();
	}

	/**
	 * Recupere un intitule
	 * @return un intitule
	 */
	public String getSubject()
	{
		return subject;
	}

	/**
	 * Specifie un intitule
	 * @param subject Un intitule
  	 */
	public void setSubject(String subject)
	{
		this.subject = subject;
	}

	/**
	 * Recupere un lieu 
	 * @return un lieu
	 */
	public String getPlace()
	{
		return place;
	}

	/**
	 * Specifie un lieu
	 * @param place Un lieu
	 */
	public void setPlace(String place)
	{
		this.place = place;
	}

	/**
	 * Recupere une date de debut 
	 * @return une date de debut
	 */
	public DateTime getStartDate()
	{
		return startDate;
	}

	/**
	 * Specifie une date de debut 
	 * @param startDate Une date de debut
	 */
	public void setStartDate(DateTime startDate)
	{
		this.startDate = startDate;
	}
	
	/**
	 * Recupere une date de fin
	 * @return une date de fin
	 */
	public DateTime getEndDate()
	{
		return startDate.plusMinutes(duration);
	}

	/**
	 * Recupere une duree
	 * @return une duree
	 */
	public int getDuration()
	{
		return duration;
	}

	/**
	 * Specifie une duree
	 * @param duration Une duree
	 */
	public void setDuration(int duration)
	{
		this.duration = duration;
	}
	
	/**
	 * Recupere des personnes
	 * @return une liste de personnes
	 */
	public List<String> getPersons()
	{
		return persons;
	}
   
	/**
	 * Ajoute une personne dans une liste de personnes
	 * @param person Une personne
	 */
	public void addPerson(String person)
	{
		persons.add(person);
	}
	
	/**
	 * Supprime une personne dans une liste de personnes
	 * @param person Une personne
	 */
	public void removePerson(String person)
	{
		persons.remove(person);
	}
	
	/**
	 * Recupere la description d'un evenement pour l'affichage
	 * @return Une chaine de caracteres decrivant un evenement
	 */
	public String getDescription()
	{
		StringBuffer description = new StringBuffer();
		
		description.append(String.format("Sujet : %s\n", subject));
		description.append(String.format("Lieu : %s\n", place));
		description.append("Personnes : ");
		
		persons = new LinkedList<String>();
		
		for(String person : persons)
		{
			description.append(String.format("%s, ", person));
		}

		return description.toString();
	}
	
	/**
	 * 
	 * @return 
	 */
	public CalendarEventEntry toCalendarEventEntry()
	{
		CalendarEventEntry eventEntry = new CalendarEventEntry();
		eventEntry.setTitle(new PlainTextConstruct(subject));
		eventEntry.setContent(new PlainTextConstruct(subject));
		eventEntry.setSummary(new PlainTextConstruct(subject));
		
		Where where = new Where();
		where.setValueString(place);
		eventEntry.addLocation(where);
		
		int zShift = TimeZone.getDefault().getRawOffset() / 60000;
		
		com.google.gdata.data.DateTime startDate = new com.google.gdata.data.DateTime(this.startDate.getMillis(), zShift);		
		com.google.gdata.data.DateTime endDate = new com.google.gdata.data.DateTime(getEndDate().getMillis(), zShift);
		When when = new When();
		when.setStartTime(startDate);		
		when.setEndTime(endDate);
		eventEntry.addTime(when);

		for(String person : persons)
		{
			EventWho who = new EventWho();
			who.setValueString(person);
			eventEntry.addParticipant(who);
		}
		
		return eventEntry;
	}
	
	/**
	 * 
	 * @return 
	 */
	public VEvent toVEvent()
	{
		net.fortuna.ical4j.model.DateTime start = new net.fortuna.ical4j.model.DateTime(startDate.getMillis());
		start.setUtc(true);
		net.fortuna.ical4j.model.DateTime end = new net.fortuna.ical4j.model.DateTime(getEndDate().getMillis());
		end.setUtc(true);
		
		Random random = new Random();
		String uid = String.format("CalDavManager - %d", Math.abs(random.nextInt()));
			
		VEvent vEvent = new VEvent(start, end, subject);
		vEvent.getProperties().add(new Uid(uid));
		vEvent.getProperties().add(new Location(place));
		vEvent.getProperties().add(new Description(getDescription()));
		return vEvent;
	}
	
	@Override
	public String toString()
	{
		return String.format("%s / %d min : %s", startDate, duration, subject);
	}
}
